home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Macintosh Tracker 1.20 / source / Tracker Client Folder / Core 18⁄March⁄1994 / MenuController.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-27  |  17.7 KB  |  707 lines  |  [TEXT/KAHL]

  1. /* MenuController.c */
  2.  
  3. #include "MenuController.h"
  4. #include "Memory.h"
  5. #include "CSack.h"
  6. #include "CWindow.h"
  7.  
  8.  
  9. #define FontMenuNameID (133L*65536L + 1)
  10.  
  11. typedef struct
  12.     {
  13.         short                MenuID;
  14.         MenuHandle    TheMenu;
  15.     } MenuListElement;
  16.  
  17. typedef struct
  18.     {
  19.         long        MenuManagerID;
  20.         short        ItemID;
  21.     } TransTableElement;
  22.  
  23.  
  24. static CSack*            TransTable;
  25. static CSack*            ListOfMenus;
  26. static short            AppleMenuID = 0;
  27. static MenuHandle    AppleMenuHandle = NIL;
  28. static short            FontMenuID;
  29. static MyBoolean    FontMenuExists = False;
  30. static short            LastSelectedFontID;
  31.  
  32. void        AddMenuToList(MenuHandle Menu, short ResID);
  33. short        FindUnusedMenuID(short IDStart);
  34. void        AddItemToList(long MenuManagerID, short ItemID);
  35. short        FindUnusedItemID(void);
  36. short        MMIDtoItemID(long MMID);
  37. long        ItemIDtoMMID(short ItemID);
  38. MenuHandle    MenuHandleFromID(short MenuID);
  39. void        DisableAll(void);
  40. void        RemoveItemFromList(long MenuManagerID, short ItemID);
  41.  
  42.  
  43. /* create the internally used data structures */
  44. void        InitMyMenus(void)
  45.     {
  46.         short                ResIndex;
  47.         MenuHandle    Menu;
  48.  
  49.         /* initializing data structures */
  50.         TransTable = new CSack;
  51.         TransTable->ISack(sizeof(TransTableElement),128);
  52.         ListOfMenus = new CSack;
  53.         ListOfMenus->ISack(sizeof(MenuListElement),128);
  54.         /* building the menus from those stored as resources */
  55.         ResIndex = 1;
  56.         while ((Menu = (MenuHandle)Get1IndResource('MENU',ResIndex)) != NIL)
  57.             {
  58.                 Reconstruct(**(short**)Menu);  /* extract menu's ID & properly reconstruct it */
  59.                 ResIndex += 1;
  60.             }
  61.     }
  62.  
  63.  
  64. /* destroy the internally used data structures */
  65. void        ShutDownMyMenus(void)
  66.     {
  67.         MenuListElement        Thang;
  68.         TransTableElement    TransThang;
  69.  
  70.         /* getting rid of menu bar (so that none of these menus are in use when they are killed */
  71.         ClearMenuBar();
  72.         DrawMenuBar();
  73.         if (FontMenuExists)
  74.             {
  75.                 DisposeMenu(MenuHandleFromID(FontMenuID));
  76.             }
  77.         /* deleting all menus from the list */
  78.         ListOfMenus->ResetScan();
  79.         while (ListOfMenus->GetNext(&Thang))
  80.             {
  81.                 DisposeMenu(Thang.TheMenu);
  82.             }
  83.         /* deleting the list itself */
  84.         delete ListOfMenus;
  85.         /* deleting the translation table */
  86.         delete TransTable;
  87.     }
  88.  
  89.  
  90. /* make an item not greyed out */
  91. void        MyEnableItem(short ItemID)
  92.     {
  93.         long                MMID;
  94.         MenuHandle    Menu;
  95.  
  96.         if (ItemID == mFontSelected)
  97.             {
  98.                 ERROR(!FontMenuExists,PRERR(ForceAbort,
  99.                     "MyEnableItem enabling nonexistent font menu"));
  100.                 EnableItem(MenuHandleFromID(FontMenuID),0);
  101.             }
  102.          else
  103.             {
  104.                 MMID = ItemIDtoMMID(ItemID);
  105.                 ERROR(MMID==0,PRERR(ForceAbort,"MyEnableItem called on nonexistent menu item."));
  106.                 Menu = MenuHandleFromID((MMID & 0xffff0000) >> 16);
  107.                 ERROR(Menu==NIL,PRERR(ForceAbort,"MyEnableItem called on item in nonexistent menu."));
  108.                 EnableItem(Menu,MMID & 0x0000ffff);
  109.             }
  110.     }
  111.  
  112.  
  113. /* make an item greyed out */
  114. void        MyDisableItem(short ItemID)
  115.     {
  116.         long                MMID;
  117.         MenuHandle    Menu;
  118.  
  119.         if (ItemID == mFontSelected)
  120.             {
  121.                 short            Scan;
  122.                 short            Limit;
  123.  
  124.                 ERROR(!FontMenuExists,PRERR(ForceAbort,
  125.                     "MyDisableItem enabling nonexistent font menu"));
  126.                 Menu = MenuHandleFromID(FontMenuID);
  127.                 Limit = CountMItems(Menu);
  128.                 for (Scan = 1; Scan <= Limit; Scan += 1)
  129.                     {
  130.                         DisableItem(Menu,Scan);
  131.                         SetItemMark(Menu,Scan,noMark);
  132.                     }
  133.             }
  134.          else
  135.             {
  136.                 MMID = ItemIDtoMMID(ItemID);
  137.                 ERROR(MMID==0,PRERR(ForceAbort,"MyDisableItem called on nonexistent menu item."));
  138.                 Menu = MenuHandleFromID((MMID & 0xffff0000) >> 16);
  139.                 ERROR(Menu==NIL,PRERR(ForceAbort,"MyDisableItem called on item in nonexistent menu."));
  140.                 DisableItem(Menu,MMID & 0x0000ffff);
  141.             }
  142.     }
  143.  
  144.  
  145. /* adjust the checkmark/hierarchicalmenuthang of a menu */
  146. void        MySetItemMark(short ItemID, char ItemMark)
  147.     {
  148.         long                MMID;
  149.         MenuHandle    Menu;
  150.  
  151.         MMID = ItemIDtoMMID(ItemID);
  152.         ERROR(MMID==0,PRERR(ForceAbort,"MySetItemMark called on nonexistent menu item."));
  153.         Menu = MenuHandleFromID((MMID & 0xffff0000) >> 16);
  154.         ERROR(Menu==NIL,PRERR(ForceAbort,"MySetItemMark called on item in nonexistent menu."));
  155.         SetItemMark(Menu,MMID & 0x0000ffff,ItemMark);
  156.     }
  157.  
  158.  
  159. /* create a new, empty menu & return its unique <resource> ID */
  160. short        CreateMenu(Handle Name)
  161.     {
  162.         short                MenuID;
  163.         MenuHandle    TheMenu;
  164.         PString            NameTemp;
  165.  
  166.         MenuID = FindUnusedMenuID(256);  /* we reserve < 256 for hierarchical menus */
  167.         Handle2PString(Name,NameTemp);
  168.         TheMenu = NewMenu(MenuID,NameTemp);
  169.         AddMenuToList(TheMenu,MenuID);
  170.         ReleaseHandle(Name);
  171.         return MenuID;
  172.     }
  173.  
  174.  
  175. /* create a new, empty hierarchical menu with a unique ID */
  176. short        CreateHierarchicalMenu(Handle Name)
  177.     {
  178.         short                MenuID;
  179.         MenuHandle    TheMenu;
  180.         PString            NameTemp;
  181.  
  182.         MenuID = FindUnusedMenuID(1);
  183.         if (MenuID >= 256)
  184.             {
  185.                 return -1;  /* allocation failed */
  186.             }
  187.         Handle2PString(Name,NameTemp);
  188.         TheMenu = NewMenu(MenuID,NameTemp);
  189.         AddMenuToList(TheMenu,MenuID);
  190.         ReleaseHandle(Name);
  191.         return MenuID;
  192.     }
  193.  
  194.  
  195. /* create a new item & add it to the specified menu */
  196. /* specify $1b for ItemShortcut to make a hierarchical menu entry */
  197. short        AddItemToMenu(short MenuID, Handle ItemName, char ItemShortcut)
  198.     {
  199.         short                ItemID;
  200.         MenuHandle    TheMenu;
  201.         PString            NameTemp;
  202.  
  203.         ItemID = FindUnusedItemID();
  204.         TheMenu = MenuHandleFromID(MenuID);
  205.         ERROR(TheMenu==0,PRERR(ForceAbort,"AddItemToMenu called on nonexistent menu."));
  206.         Handle2PString(ItemName,NameTemp);
  207.         AppendMenu(TheMenu,"\px");
  208.         SetItem(TheMenu,CountMItems(TheMenu),NameTemp);
  209.         SetItemCmd(TheMenu,CountMItems(TheMenu),ItemShortcut);
  210.         AddItemToList( ((((long)MenuID)<<16) & 0xffff0000) |
  211.             (0x0000ffff & CountMItems(TheMenu)), ItemID);
  212.         ReleaseHandle(ItemName);
  213.         return ItemID;
  214.     }
  215.  
  216.  
  217. void        DeleteItemFromMenu(short ItemID)
  218.     {
  219.         long                MMID;
  220.         MenuHandle    Menu;
  221.  
  222.         MMID = ItemIDtoMMID(ItemID);
  223.         Menu = MenuHandleFromID((MMID >> 16) & 0x0000ffff);
  224.         DelMenuItem(Menu,MMID & 0x0000ffff);
  225.         RemoveItemFromList(MMID,ItemID);
  226.     }
  227.  
  228.  
  229. void        ChangeName(short ItemID, Handle NewName)
  230.     {
  231.         MenuHandle    TheMenu;
  232.         long                MMID;
  233.         PString            TempStr;
  234.  
  235.         MMID = ItemIDtoMMID(ItemID);
  236.         ERROR(MMID==0,PRERR(ForceAbort,"ChangeName called on nonexistent item."));
  237.         TheMenu = MenuHandleFromID((MMID >> 16) & 0x0000ffff);
  238.         ERROR(TheMenu==NIL,PRERR(ForceAbort,"ChangeName found an item for a nonexistent menu."));
  239.         Handle2PString(NewName,TempStr);
  240.         ReleaseHandle(NewName);
  241.         SetItem(TheMenu,(MMID & 0x0000ffff),TempStr);
  242.     }
  243.  
  244.  
  245. /* add a menu to the menu bar.  If it's ID indicates it's hierarchical then add it to that part */
  246. void        PostMenuToBar(short MenuID)
  247.     {
  248.         MenuHandle    TheMenu;
  249.  
  250.         TheMenu = MenuHandleFromID(MenuID);
  251.         ERROR(TheMenu==NIL,PRERR(ForceAbort,"PostMenuToBar called on nonexistent menu."));
  252.         if (MenuID < 256)
  253.             {
  254.                 InsertMenu(TheMenu,-1);  /* hierarchical menus have IDs less than 256 */
  255.             }
  256.          else
  257.             {
  258.                 InsertMenu(TheMenu,0);  /* normals get APPENDED to the menu */
  259.             }
  260.         EnableItem(TheMenu,0); /* make sure menu title is enabled */
  261.         DrawMenuBar();
  262.     }
  263.  
  264.  
  265. /* remove any kind of menu from the menu bar list */
  266. void        RemoveMenuFromBar(short MenuID)
  267.     {
  268.         DeleteMenu(MenuID);
  269.         DrawMenuBar();
  270.     }
  271.  
  272.  
  273. /* mouse down occurred--track menu bar & return ID of item */
  274. short        MenuMouseDown(EventRecord* TheEvent)
  275.     {
  276.         long            MenuManagerID;
  277.         MyBoolean    Status;
  278.  
  279.         DisableAll(); /* disable all menu items */
  280.         if (ActiveWindow != NIL)
  281.             {
  282.                 ActiveWindow->EnableMenuItems(); /* enable menu items that can be used now */
  283.             }
  284.         MenuManagerID = MenuSelect(TheEvent->where);
  285.  
  286.         /* checking for user changing his mind */
  287.         if ((MenuManagerID & 0xffff0000) == 0)
  288.             {
  289.                 return mNoItem;
  290.             }
  291.  
  292.         /* some obsolete system 6 nonsense */
  293. #if 0
  294.         if (SystemEdit((MenuManagerID & 0x0000ffff) - 1))
  295.             {
  296.                 return mNoItem;
  297.             }
  298. #endif
  299.  
  300.         /* checking for Font menu */
  301.         if (((MenuManagerID & 0xffff0000) >> 16) == FontMenuID)
  302.             {
  303.                 PString        FontName;
  304.  
  305.                 GetItem(MenuHandleFromID((MenuManagerID & 0xffff0000) >> 16),
  306.                     MenuManagerID & 0x0000ffff,FontName);
  307.                 LastSelectedFontID = GetFontID(FontName);
  308.                 return mFontSelected;
  309.             }
  310.  
  311.         /* checking for Desk accessory open */
  312.         if ((((MenuManagerID & 0xffff0000) >> 16) == AppleMenuID)
  313.             && ((MenuManagerID & 0x0000ffff) != 1))
  314.             {
  315.                 PString        DeskAccName;
  316.  
  317.                 ERROR(AppleMenuHandle==NIL,PRERR(ForceAbort,"AppleMenuHandle == NIL."));
  318.                 GetItem(AppleMenuHandle,MenuManagerID & 0x0000ffff,DeskAccName);
  319.                 OpenDeskAcc(DeskAccName);
  320.                 return mNoItem;
  321.             }
  322.  
  323.         /* finally, we can return the item!!! */
  324.         return MMIDtoItemID(MenuManagerID);
  325.     }
  326.  
  327.  
  328. /* attempt to decode a keyboard shortcut */
  329. short        MenuKeyDown(EventRecord* TheEvent)
  330.     {
  331.         long            MenuManagerID;
  332.         MyBoolean    Status;
  333.  
  334.         DisableAll(); /* disable all menu items */
  335.         if (ActiveWindow != NIL)
  336.             {
  337.                 ActiveWindow->EnableMenuItems(); /* enable menu items that can be used now */
  338.             }
  339.         MenuManagerID = MenuKey(TheEvent->message & 0x000000ff);
  340.         if ((MenuManagerID & 0xffff0000) == 0)
  341.             {
  342.                 return mNoItem;
  343.             }
  344.          else
  345.             {
  346.                 if (/*SystemEdit((MenuManagerID & 0x0000ffff) - 1)*/False)
  347.                     {
  348.                         return mNoItem;
  349.                     }
  350.                  else
  351.                     {
  352.                         return MMIDtoItemID(MenuManagerID);
  353.                     }
  354.             }
  355.     }
  356.  
  357.  
  358. /* take the specified resource id, destroy any existing menus tied to it, load the resource */
  359. /* from the file, strip ItemID numbers embedded in the strings, and create an internal menu */
  360. /* this routine expects the menu NOT to be on the menu bar at the time */
  361. void        Reconstruct(short MenuID)
  362.     {
  363.         Handle                        ResMenu;
  364.         uchar*                        PMenu;
  365.         long                            Scan;
  366.         MenuHandle                OurMenu;
  367.  
  368.         RemoveMenuFromBar(MenuID); /* remove it from the menu bar */
  369.         MyDeleteMenu(MenuID);  /* call this to get rid of the old one if there is one */
  370.         /* getting the resource menu template */
  371.         ERROR(ResLoad == 0,PRERR(ForceAbort,"Automatic resource loading is disabled."));
  372.         ResMenu = GetResource('MENU',MenuID);
  373.         ERROR(ResErr != noErr,PRERR(ForceAbort,"Resource Error occurred."));
  374.         MoveHHi(ResMenu);
  375.         HLock(ResMenu);
  376.         PMenu = (uchar*)*ResMenu;
  377.         /* now reconstructing the items */
  378.         Scan = 14;  /* starting position of menu name */
  379.         OurMenu = NewMenu(MenuID,&(PMenu[Scan]));  /* create the menu */
  380.         AddMenuToList(OurMenu,MenuID);  /* add it to the list */
  381.         Scan = Scan + 1 + (PMenu[Scan]);  /* add in the length of the string */
  382.         while ((PMenu[Scan]) != 0) /* adding items as they occur */
  383.             {
  384.                 short        i;
  385.                 short        ItemID;
  386.  
  387.                 i = 0;
  388.                 while (i<PMenu[Scan]) /* scan over the string */
  389.                     {
  390.                         if (PMenu[Scan+i+1] == '\\')
  391.                             {
  392.                                 long        Temp;
  393.  
  394.                                 /* strip the command info from the menu definition & add the item */
  395.                                 ItemID = Hex2Byte(PMenu[Scan+i+2]);
  396.                                 ItemID = (ItemID*16) + Hex2Byte(PMenu[Scan+i+3]);
  397.                                 ItemID = (ItemID*16) + Hex2Byte(PMenu[Scan+i+4]);
  398.                                 ItemID = (ItemID*16) + Hex2Byte(PMenu[Scan+i+5]);
  399.                                 Temp = Scan;
  400.                                 Scan = Scan + 1 + (PMenu[Scan]);  /* skip over menu name */
  401.                                 PMenu[Temp] = i;  /* new string length */
  402.                                 AppendMenu(OurMenu,"\px");  /* add string to the menu */
  403.                                 SetItem(OurMenu,CountMItems(OurMenu),&(PMenu[Temp]));
  404.                                 goto ResumePoint;  /* escape */
  405.                             }
  406.                          else
  407.                             {
  408.                                 i += 1;
  409.                             }
  410.                     }
  411.                 ItemID = FindUnusedItemID();  /* create dummy ID if no ID is specified in resource */
  412.                 AppendMenu(OurMenu,"\px");  /* add the string to the menu */
  413.                 SetItem(OurMenu,CountMItems(OurMenu),&(PMenu[Scan]));
  414.                 Scan = Scan + 1 + (PMenu[Scan]);  /* skip over menu name */
  415.              ResumePoint:
  416.                 SetItemCmd(OurMenu,CountMItems(OurMenu),PMenu[Scan+1]); /* set command key equivalent */
  417.                 Scan = Scan + 4;  /* 4 other bytes in the menu definition */
  418.                 AddItemToList( ((((long)MenuID)<<16) & 0xffff0000) |
  419.                     (0x0000ffff & CountMItems(OurMenu)), ItemID);  /* put it in the translation table */
  420.             }
  421.         HUnlock(ResMenu);
  422.         ReleaseResource(ResMenu);
  423.         if (((**OurMenu).menuData[0] == 1) && ((**OurMenu).menuData[1] == 0x14))
  424.             {
  425.                 /* then it's the apple menu, so add desk accessories. */
  426.                 AddResMenu(OurMenu,'DRVR');
  427.                 AppleMenuID = MenuID;
  428.                 AppleMenuHandle = OurMenu;
  429.             }
  430.     }
  431.  
  432.  
  433. /********************************************************************************/
  434. /* private routines */
  435.  
  436.  
  437. /* auxiliary routine to add menu to the list */
  438. void        AddMenuToList(MenuHandle Menu, short ResID)
  439.     {
  440.         MenuListElement        Temp;
  441.  
  442.         Temp.MenuID = ResID;
  443.         Temp.TheMenu = Menu;
  444.         ListOfMenus->PushElement(&Temp);
  445.     }
  446.  
  447.  
  448. /* auxiliary routine to find an unused Menu ID number starting somewhere */
  449. short        FindUnusedMenuID(short IDStart)
  450.     {
  451.         MenuListElement        Temp;
  452.         short                            MenuIDTemp;
  453.  
  454.         MenuIDTemp = IDStart;
  455.      RestartPoint:
  456.         ListOfMenus->ResetScan();
  457.         while (ListOfMenus->GetNext(&Temp))
  458.             {
  459.                 if (Temp.MenuID == MenuIDTemp)
  460.                     {
  461.                         MenuIDTemp += 1;
  462.                         goto RestartPoint;
  463.                     }
  464.             }
  465.         return MenuIDTemp;
  466.     }
  467.  
  468.  
  469. /* auxiliary routine to add item to the list */
  470. void        AddItemToList(long MenuManagerID, short ItemID)
  471.     {
  472.         TransTableElement        Temp;
  473.  
  474.         Temp.MenuManagerID = MenuManagerID;
  475.         Temp.ItemID = ItemID;
  476.         TransTable->PushElement(&Temp);
  477.     }
  478.  
  479.  
  480. /* auxiliary routine to remove item from the item list */
  481. /* we have reassign MenuManagerIDs to all items in the same menu after this */
  482. /* one since they will all be shifted up one. */
  483. void        RemoveItemFromList(long MenuManagerID, short ItemID)
  484.     {
  485.         TransTableElement        Temp;
  486.  
  487.         Temp.MenuManagerID = MenuManagerID;
  488.         Temp.ItemID = ItemID;
  489.         TransTable->KillElement(&Temp);
  490.         TransTable->ResetScan();
  491.         while (TransTable->GetNext(&Temp))
  492.             {
  493.                 if ((Temp.MenuManagerID & 0xffff0000) == (MenuManagerID & 0xffff0000))
  494.                     {
  495.                         if ((Temp.MenuManagerID & 0x0000ffff) > (MenuManagerID & 0x0000ffff))
  496.                             {
  497.                                 MyBoolean            Success;
  498.  
  499.                                 Temp.MenuManagerID = (Temp.MenuManagerID & 0xffff0000)
  500.                                     | (((Temp.MenuManagerID & 0x0000ffff) - 1) & 0x0000ffff);
  501.                                 Success = TransTable->RewriteCurrent(&Temp);
  502.                                 ERROR(!Success,PRERR(AllowResume,
  503.                                     "RemoveItemFromList RewriteCurrent failed"));
  504.                             }
  505.                     }
  506.             }
  507.     }
  508.  
  509.  
  510. /* auxiliary routine to find an unused Item ID number starting somewhere */
  511. short        FindUnusedItemID(void)
  512.     {
  513.         TransTableElement        Temp;
  514.         ushort                            TempID;
  515.  
  516.         TempID = 0xffff;
  517.      RestartPoint:
  518.         TransTable->ResetScan();
  519.         while (TransTable->GetNext(&Temp))
  520.             {
  521.                 if (Temp.ItemID == TempID)
  522.                     {
  523.                         TempID -= 1;
  524.                         goto RestartPoint;
  525.                     }
  526.             }
  527.         return TempID;
  528.     }
  529.  
  530.  
  531. /* convert a MenuManagerID to an ItemID */
  532. short        MMIDtoItemID(long MMID)
  533.     {
  534.         TransTableElement        Temp;
  535.  
  536.         TransTable->ResetScan();
  537.         while (TransTable->GetNext(&Temp))
  538.             {
  539.                 if (Temp.MenuManagerID == MMID)
  540.                     {
  541.                         return Temp.ItemID;
  542.                     }
  543.             }
  544.         EXECUTE(PRERR(AllowResume,"Undefined menu item position ID referenced."));
  545.         EXECUTE(return -1);
  546.     }
  547.  
  548.  
  549. /* convert an ItemID to a MenuManagerID */
  550. long        ItemIDtoMMID(short ItemID)
  551.     {
  552.         TransTableElement        Temp;
  553.  
  554.         TransTable->ResetScan();
  555.         while (TransTable->GetNext(&Temp))
  556.             {
  557.                 if (Temp.ItemID == ItemID)
  558.                     {
  559.                         return Temp.MenuManagerID;
  560.                     }
  561.             }
  562.         EXECUTE(PRERR(AllowResume,"Undefined menu item local ID referenced."));
  563.         EXECUTE(return 0);
  564.     }
  565.  
  566.  
  567. /* take the menu ID and find the handle referring to that menu. */
  568. /* returns NIL if it couldn't find anything */
  569. MenuHandle    MenuHandleFromID(short MenuID)
  570.     {
  571.         MenuListElement        Temp;
  572.  
  573.         ListOfMenus->ResetScan();
  574.         while (ListOfMenus->GetNext(&Temp))
  575.             {
  576.                 if (Temp.MenuID == MenuID)
  577.                     {
  578.                         return Temp.TheMenu;
  579.                     }
  580.             }
  581.         return NIL;
  582.     }
  583.  
  584.  
  585. /* utterly delete a menu (assume it has been removed from the bar) */
  586. void        MyDeleteMenu(short MenuID)
  587.     {
  588.         MenuListElement            MTemp;
  589.         TransTableElement        ITemp;
  590.         void*                                Temp;
  591.         long                                Scan;
  592.         MenuHandle                    HandleTemp;
  593.  
  594.         /* destroying the old menu */
  595.         HandleTemp = MenuHandleFromID(MenuID);
  596.         if (HandleTemp != NIL)
  597.             {
  598.                 DisposeMenu(HandleTemp);  /* dispose the menu */
  599.             }
  600.         /* removing menu record from list */
  601.      LoopPoint1:
  602.         ListOfMenus->ResetScan();
  603.         while (ListOfMenus->GetNext(&MTemp))
  604.             {
  605.                 if (MTemp.MenuID == MenuID)
  606.                     {
  607.                         ListOfMenus->KillElement(&MTemp);
  608.                         goto LoopPoint1;
  609.                     }
  610.             }
  611.         /* removing translation table entries */
  612.      LoopPoint2:
  613.         TransTable->ResetScan();
  614.         while (TransTable->GetNext(&ITemp))
  615.             {
  616.                 if ( ((ITemp.MenuManagerID & 0xffff0000) >> 16) == MenuID)
  617.                     {
  618.                         TransTable->KillElement(&ITemp);
  619.                         goto LoopPoint2;
  620.                     }
  621.             }
  622.     }
  623.  
  624.  
  625. /* disable all menu items */
  626. void        DisableAll(void)
  627.     {
  628.         TransTableElement        Temp;
  629.         MenuHandle                    Menu;
  630.         long                                NumElements;
  631.         long                                Scan;
  632.  
  633.         TransTable->ResetScan();
  634.         while (TransTable->GetNext(&Temp))
  635.             {
  636.                 short                TempCmd;
  637.  
  638.                 Menu = MenuHandleFromID((Temp.MenuManagerID & 0xffff0000) >> 16);
  639.                 DisableItem(Menu,Temp.MenuManagerID & 0x0000ffff);
  640.                 GetItemCmd(Menu,Temp.MenuManagerID & 0x0000ffff,&TempCmd);
  641.                 if (TempCmd != 0x001b)
  642.                     {
  643.                         /* disable item's mark if it is not a hierarchical menu */
  644.                         SetItemMark(Menu,Temp.MenuManagerID & 0x0000ffff,noMark);
  645.                     }
  646.             }
  647.         if (FontMenuExists)
  648.             {
  649.                 short            Scan;
  650.                 short            Limit;
  651.  
  652.                 ERROR(!FontMenuExists,PRERR(ForceAbort,
  653.                     "MyDisableItem enabling nonexistent font menu"));
  654.                 Menu = MenuHandleFromID(FontMenuID);
  655.                 Limit = CountMItems(Menu);
  656.                 for (Scan = 1; Scan <= Limit; Scan += 1)
  657.                     {
  658.                         DisableItem(Menu,0);
  659.                         SetItemMark(Menu,Scan,noMark);
  660.                     }
  661.             }
  662.     }
  663.  
  664.  
  665. /* add a font menu */
  666. short        AddFontMenu(void)
  667.     {
  668.         ERROR(FontMenuExists,PRERR(AllowResume,"AddFontMenu called when one already exists"));
  669.         FontMenuExists = True;
  670.         FontMenuID = CreateMenu(GetCString(FontMenuNameID));
  671.         AddResMenu(MenuHandleFromID(FontMenuID),'FONT');
  672.         return FontMenuID;
  673.     }
  674.  
  675.  
  676. /* find out which font was selected */
  677. short        GetLastFontID(void)
  678.     {
  679.         return LastSelectedFontID;
  680.     }
  681.  
  682.  
  683. /* determine which font will be set */
  684. void        SetFontMark(short FontID)
  685.     {
  686.         PString            FontName;
  687.         MenuHandle    Menu;
  688.         short                Scan;
  689.         short                Limit;
  690.         PString            ItemName;
  691.  
  692.         ERROR(!FontMenuExists,PRERR(AllowResume,"SetFontMark called when no font menu exists"));
  693.         GetFontName(FontID,FontName);
  694.         Menu = MenuHandleFromID(FontMenuID);
  695.         Limit = CountMItems(Menu);
  696.         for (Scan = 1; Scan <= Limit; Scan += 1)
  697.             {
  698.                 GetItem(Menu,Scan,ItemName);
  699.                 if (MemEqu((char*)FontName,(char*)ItemName,FontName[0] + 1))
  700.                     {
  701.                         SetItemMark(Menu,Scan,checkMark);
  702.                         return;
  703.                     }
  704.             }
  705.         /* font not found, but who cares! */
  706.     }
  707.